from pathlib import Path
from typing import Optional, List

from openpyxl import load_workbook
from pydantic import BaseModel

from .export_as_excel import Exporter
from .import_from_excel import (
    import_products_from_tender,
    import_products_from_bid,
    unmerge_and_fill_cells,
)
from .process import add_supplier
from .schema import SummaryTable

AVAILABLE_SHEET_NAMES = ["报价单"]


class Bidder(BaseModel):
    name: str
    document: Path
    has_bargaining: bool = False
    bargaining_document: Optional[Path] = None


class Consolidator:
    def __init__(self, tender_document: Path, summary_document: Path):
        self.tender_document = tender_document
        self.summary_document = summary_document
        self.summary_tables: List[SummaryTable] = []

    def load_tender(self):
        tender_workbook = load_workbook(self.tender_document, data_only=True)
        sheet_names = tender_workbook.sheetnames
        valid_sheet_names = [
            name for name in sheet_names if name in AVAILABLE_SHEET_NAMES
        ]
        for sheet_name in valid_sheet_names:
            sheet = tender_workbook[sheet_name]
            unmerge_and_fill_cells(sheet)
            summary_table = import_products_from_tender(sheet)
            self.summary_tables.append(summary_table)
        tender_workbook.close()

    def add_bids(self, bid_documents: List[Bidder]):
        for bid_document in bid_documents:
            print(f"Processing bid from supplier: {bid_document.name}")
            try:
                self._add_bid(
                    supplier_name=bid_document.name,
                    document=bid_document.document,
                    is_bargaining=False,
                )
            except Exception as e:
                raise e

            # 记录哪些供应商有二次议价
            if bid_document.has_bargaining:
                try:
                    self._add_bid(
                        supplier_name=bid_document.name,
                        document=bid_document.bargaining_document,
                        is_bargaining=True,
                    )
                except Exception as e:
                    raise e

    def _add_bid(self, supplier_name: str, document: Path, is_bargaining: bool = False):
        wb = load_workbook(document)
        sheet_names = [name for name in wb.sheetnames if name in AVAILABLE_SHEET_NAMES]
        for sheet_name in sheet_names:
            print(f"  Adding bid for sheet: {sheet_name}")
            sheet = wb[sheet_name]
            unmerge_and_fill_cells(sheet)

            try:
                # 获取有效表头（最多检查前20列）
                headers = []
                for col in range(1, 21):
                    cell_value = sheet.cell(row=1, column=col).value
                    if cell_value and str(cell_value).strip():
                        headers.append(str(cell_value).strip())
                    elif len(headers) > 0:  # 已有表头后遇到空列则停止
                        break

                print(f"识别到的表头: {headers}")  # 调试信息

                # 定义必须列（主名称+兼容名称）
                required_columns = {
                    "序号": ["序号"],
                    "产品代码": ["产品代码"],
                    "产品名称": ["产品名称", "名称"],
                    "规格型号": ["规格型号（带指示灯）", "规格型号", "(带指示灯)"],
                    "单位": ["单位"],
                    "单价": ["单价", "报价", "含税单价"],  # 统一处理报价和单价
                }

                # 检查各列是否存在
                found_columns = {}
                for header in headers:
                    for col_type, aliases in required_columns.items():
                        if header in aliases:
                            found_columns[col_type] = True

                # 检查是否有缺失列
                missing = [col for col in required_columns if col not in found_columns]
                if missing:
                    raise ValueError(f"缺少必要列: {missing}。识别到的表头: {headers}")

                # 标记是否为特殊格式（带指示灯单独成列）
                is_special_format = "(带指示灯)" in headers

            except Exception as e:
                raise Exception(
                    f"{supplier_name}的{'二次' if is_bargaining else ''}报价文件格式有误: {str(e)}"
                )

            # 导入数据时传递特殊格式标记
            bid_table = import_products_from_bid(
                sheet=sheet,
                supplier=supplier_name,
                is_bargaining=is_bargaining,
                is_special_format=is_special_format,
            )

            # ...其余合并逻辑保持不变...
            for summary_table in self.summary_tables:
                if summary_table.table_name == bid_table.table_name:
                    add_supplier(summary_table, bid_table)
                    if supplier_name not in summary_table.suppliers:
                        summary_table.suppliers.append(supplier_name)
                    if (
                        is_bargaining
                        and supplier_name not in summary_table.suppliers_with_bargaining
                    ):
                        summary_table.suppliers_with_bargaining.append(supplier_name)
                    break
        wb.close()

    def save(self):
        for table in self.summary_tables:
            print(
                f"Summary Table: {table.table_name}, Products: {len(table.products)}, Suppliers: {len(table.suppliers)}"
            )
        exporter = Exporter(self.summary_tables)
        exporter.export(str(self.summary_document))
